package com.liting.uitest.imgutils;

import com.liting.uitest.model.*;
import com.liting.uitest.service.impl.ImageCacheService;
import lombok.extern.slf4j.Slf4j;
import org.opencv.core.Mat;
import org.opencv.imgproc.Imgproc;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 垂直对称性计算
 */
@Service
@Slf4j
public class VerticaSymmetry {
    @Autowired
    private ImageCacheService cacheService;
    @Autowired
    private VerticaSymmetryExcecutor excecutor;

    public BigDecimal vsCalc(Long fileId, List<Rectangle> rectList, List<Circle> cirList) throws Exception {
        ImageInfo imageInfo = cacheService.getImage(fileId);
        if (imageInfo == null) {
            throw new Exception("文件不存在");
        }

        // 获取图像的宽度和高度
        int width = imageInfo.getWidth();
        int height = imageInfo.getHeight();

        int allArea = 0, sameArea = 0;
        List<ImagePixel> allPixel = new ArrayList<>();

        Mat grayMat = OpenCVImageUtils.getGrapMat(imageInfo.getColorImage());

        List<CompletableFuture<VSExecutorResult>> futureList = new ArrayList<>();

        for (int row = 0; row < height / 100; row++) {
            futureList.add(excecutor.vsCalc(grayMat, width,
                    row * 100, (row + 1) * 100, rectList, cirList));
        }
        futureList.add(excecutor.vsCalc(grayMat, width,
                (height / 100) * 100, height + 1, rectList, cirList));

        // 手动阻塞主线程,直至业务线程完成返回
        CompletableFuture<VSExecutorResult>[] resultArray = new CompletableFuture[futureList.size()];
        int i = 0;
        for (CompletableFuture<VSExecutorResult> temp : futureList) {
            resultArray[i++] = temp;
        }
        CompletableFuture.allOf(resultArray).join();

        log.info("all executor over");

        try {
            allArea = 0;
            sameArea = 0;
            for (int j = 0; j < resultArray.length; j++) {
                allArea = allArea + resultArray[j].get().getAllArea();
                sameArea = sameArea + resultArray[j].get().getSameArea();
            }
        } catch (Exception ex) {
            log.error("异步处理失败", ex);
            throw new Exception("计算失败");
        }
        BigDecimal result = BigDecimal.valueOf(sameArea / (double) allArea).setScale(2, RoundingMode.UP);


        return result;
    }


}
